package com.hhck.filter;

import com.alibaba.fastjson.JSON;
import com.hhck.constants.Constants;
import com.hhck.entity.Result;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义登录限制过滤器
 */
public class LoginCheckFilter implements Filter {

    // Redis模板成员变量
    private StringRedisTemplate redisTemplate;
    // 提供set方法（当前类不被Spring容器管理无法直接注入，所以在注册过滤器时设置Redis模板）
    public void setRedisTemplate(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 设置请求接口白名单
        List<String> whiteList = new ArrayList<>();
        whiteList.add("/captcha/captchaImage"); // 验证码图片生成
        whiteList.add("/login");                // 登录
        whiteList.add("/logout");               // 退出登录
        whiteList.add("/product/img-upload");   // 图片上传（添加商品图片的请求）

        // 获取请求url接口
        String url = request.getServletPath();
        // 判断当前请求的接口是否在白名单内 或者 请求接口中是否包含图片路径（访问本地静态资源的请求）
        if (whiteList.contains(url) || url.contains("/img/upload")) {
            // 白名单内的请求 或者 本地静态资源的请求直接放行
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        // 其他请求需要验证请求头是否携带合法token

        // 获取请求头携带的token
        String token = request.getHeader(Constants.HEADER_TOKEN_NAME);
        // 判断是否携带token，以及是否和Redis中的token一致
        if (StringUtils.hasText(token) && redisTemplate.hasKey(token)) {
            // 一致，放行
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        // 不一致，不放行，给前端响应数据

        // 设置响应数据
        Result result = Result.err(Result.CODE_ERR_UNLOGINED, "尚未登录！");
        String jsonResult = JSON.toJSONString(result);

        // 设置响应内容类型
        response.setContentType("application/json;charset=utf-8");
        // 获取输出流，并将数据响应给前端
        PrintWriter out = response.getWriter();
        out.write(jsonResult);
        out.flush();
        out.close();
    }

}

